package com.longe.security;

import com.longe.entity.User;
import com.longe.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    /**当前ream的名称**/
    @Override
    public void setName(String name) {
        super.setName("currentReamName");
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        User user = userService.selectUserByName(userToken.getUsername());

        if(null == user){
            //当前用户不存在
            throw new UnknownAccountException();
        }

        //根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为: SimpleAuthenticationInfo
        //以下信息是从数据库中获取的.
        //1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.
        Object principal = user;
        //2). credentials: 密码.
        Object credentials = user.getPassword();
        //3). realmName: 当前 realm 对象的 name.
        String realmName = getName();

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, ByteSource.Util.bytes(user.getSalt()), realmName);
        return info;
    }

    /**
     * 授权
     * @param principalCollection 包含了所有已认证安全数据
     * @return AuthorizationInfo 授权数据
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        /**这里为了简单演示,就不从数据库中获取了**/
        /*User user = (User) principalCollection.getPrimaryPrincipal();

        Set<String> roles = userRoleService.selectUserRoles(user.getId());
        Set<String> permissions = rolePermissionService.selectUserPermissions(user.getId());

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;*/

        Set<String> roles = new HashSet<>();
        roles.add("user");

        Set<String> permissions = new HashSet<>();
        //permissions.add("customer:*"); 这样等于配置了客户的所有权限
        permissions.add("customer:detail");
        permissions.add("customer:add");
        permissions.add("customer:query");

        //设置针对于自定义过滤器的权限,通过请求的url来判断权限
        permissions.add("/customize/detail");
        permissions.add("/customize/query");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }

}
